<template>
    <el-dialog v-model="dialog.show"
               :title="dialog.title"
               @close="doDialogClose">
        <el-form
                :model="forms.data"
                ref="formsRef"
                :rules="forms.rules"
                :label-width="formOptions?.labelWidth ? formOptions.labelWidth : '120px'"
                :label-position="formOptions?.labelPosition ? formOptions.labelPosition : 'right'"
        >
            <slot name="formItem" :data="forms.data"></slot>
        </el-form>
        <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="doSubmit(formsRef)"> 确定 </el-button>
        <el-button @click="dialog.show = false">取消</el-button>
      </span>
        </template>
    </el-dialog>
</template>
<script setup type="ts">
import {defineEmits, defineExpose, defineProps, onMounted, reactive, ref} from "vue";

const emit = defineEmits(["submit"]);
const forms = reactive({
    data: {},
    rules: {}
});
const dialog = reactive({show: false, title: '', id: null})
const props = defineProps({
    rules: {
        type: Object
    },
    fields: {
        type: Array
    },
    detail: {
        type: Object
    },
    formOptions: {
        type: Object,
        default: () => {
        }
    }
});

const formsRef = ref();
const doSubmit = async (formEl) => {
    if (!formEl) return;
    await formEl.validate((valid, fields) => {
        if (valid) {
            emit("submit", forms.data);
            doDialogClose();
        } else {
            console.log("error submit!", fields);
        }
    });
};

const doDialogOpen = (params) => {
    dialog.show = params.show;
    dialog.id = params.id;
    dialog.title = params.title;
    forms.data = {}
    // 如果有id则查询数据
    if (dialog.id && props.detail.api) {
        props.detail.api({id: params.id}).then(res => {
            forms.data = res.data || {};
        })
    }
}

const doDialogClose = () => {
    dialog.show = false;
    dialog.id = null;
    dialog.title = '';
}

const exposed = {
    doDialogOpen
};

onMounted(() => {
    // 处理校验规则
    props.fields.forEach(e => {
        forms.rules[e.name] = [];
        if (e.required) {
            const v = {required: true, message: '请输入' + e.label, trigger: 'blur'};
            forms.rules?.[e.name]?.push(v);
        }
        if (e.maxLength) {
            const v = {
                max: e.maxlength,
                message: e.label + '最长不能超过' + e.maxlength + '个字符',
                trigger: 'blur'
            }
            forms.rules?.[e.name]?.push(v);
        }

        if (e.minLength) {
            const v = {
                max: e.minLength,
                message: e.label + '不能少于' + e.maxlength + '个字符',
                trigger: 'blur'
            }
            forms.rules?.[e.name]?.push(v);
        }

        if (e.validate) {
            const v = {
                validator: (rule, value, callback) => {
                    // 提交前处理
                    if (props.formOptions && props.formOptions.onBeforeSubmit) {
                        props.formOptions.onBeforeSubmit(forms.data);
                    }
                    e.validate(forms.data).then(res => {
                        const data = res.data
                        if (data === false) {
                            callback(new Error(e.label + "重复"))
                        } else {
                            callback();
                        }
                    })
                }, trigger: 'blur'
            };
            forms.rules?.[e.name]?.push(v);
        }
    });
    if (props.rules) {
        Object.keys(props.rules).forEach(key => {
            const values = forms.rules[key] || [];
            values.push(props.rules[key]);
            forms.rules[key] = values;
        })
    }
})

defineExpose(exposed);
</script>
